package com.meida.module.virbox.provider.virboxProvider.service.impl;

import com.google.gson.Gson;
import com.meida.common.utils.ApiAssert;
import com.meida.common.utils.DateUtils;
import com.meida.common.utils.JsonUtils;
import com.meida.common.utils.RedisUtils;
import com.meida.module.virbox.provider.entity.AuthToken;
import com.meida.module.virbox.provider.virboxProvider.model.SLMLicense;
import com.meida.module.virbox.provider.virboxProvider.model.SoftwareLicense;
import com.meida.module.virbox.provider.virboxProvider.service.LicenseProvider;
import com.senseyun.openapi.SSRuntimeEasyJava.*;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@Slf4j
public class SenseshieldLicenseProvider implements LicenseProvider {
//	@Value("${manage.web.holder.name}")
//	private String holder;
	private static final String devId = "D3B51B4D21AE947158159761E110DF97";
	@Value("${virbox.licenseId:20220101}")
	private int softwareId;
	private SoftwareLicense license;
	@Autowired
	private RedisUtils redisUtils;

//	@Override
//	public String getHolder() {
//		return holder;
//	}
//
//	public void setHolder(String holder) {
//		this.holder = holder;
//	}

	public SenseshieldLicenseProvider() {

		try{
			long ret = 0;
			// test SlmInitEasy SlmErrorFormatEasy
			ret = SSRuntimeEasy.SlmInitEasy(devId);
			log.info("加密狗返回信息{}",ret);
			if (ret == ErrorCode.SS_OK) {
				System.out.println("SlmInitEasy success !");
			} else {
				log.error("加载加密狗库文件失败");
				//throw new IllegalAccessError("加载加密狗库文件失败");
			}
		}catch(Throwable e){
			log.error("加密狗程序初始化异常",e);
		}

	}

	@Override
	public SoftwareLicense getLicense() {
		return null;
//		String dayKey = DateUtils.formatDate();
//		try{
//			Object obj = redisUtils.get(dayKey);
//			SoftwareLicense license = null;
//			if(obj!=null){
//				license = (SoftwareLicense)license;
//			}
//			if(license==null||!license.isEnable()){
//				license = readLicense();
//				redisUtils.set(dayKey,license,60*60*24L);
//			}
//			if(license.isEnable()){
//				if(license.isLimited()){//限制时间
//					if(license.getEndTime().getTime()<System.currentTimeMillis()){
//						redisUtils.del(dayKey);
//						ApiAssert.failure("授权已过期，请联系厂商重新授权");
//					}
//				}
//			}else{
//				redisUtils.del(dayKey);
//				ApiAssert.failure("暂无授权，请联系厂商进行授权");
//			}
//		}catch(Throwable e){
//			redisUtils.del(dayKey);
//		}
//		return license;
	}


	@Override
	public AuthToken getAuthToken(){
		AuthToken authToken = null;
		try {
			long ret = 0;
//			// 初始化函数，在使用深思RuntimeAPI其他接口之前，必须调用初始化函数
//			ret = SSRuntimeEasy.SlmInitEasy(devId);
//			if (ret == ErrorCode.SS_OK) {
//				System.out.println("SlmInitEasy success !");
//			} else {
//				System.out.printf("SlmInitEasy failure : 0x%08X!  %s\n", ret, SSRuntimeEasy.SlmErrorFormatEasy(ret, 2));
//			}
			long Handle = 0;
			//struct
			ST_LOGIN_PARAM stLogin = new ST_LOGIN_PARAM();
			stLogin.size = stLogin.getSize();
			stLogin.license_id = softwareId;
			//stLogin.user_guid = stringToHexByte("123456");  //(可选)
			//Handle = SSRuntimeEasy.SlmLoginEasy(Param, INFO_FORMAT_TYPE.JSON.get());     //login by json  （不支持）
			Handle = SSRuntimeEasy.SlmLoginEasy(stLogin, INFO_FORMAT_TYPE.STRUCT.get());   //login by struct
			ret = SSRuntimeEasy.SlmGetLastError();
			if (ret == ErrorCode.SS_OK && Handle != 0) {
				System.out.println("SlmLoginEasy success!");
				System.out.printf("[SLM Handle]: %d\n", Handle);
			} else {
				System.out.printf("SlmLoginEasy failure : ErrorCode = 0x%08X!   SLM Handle = %d\n", ret, Handle);
			}


			//json 为确保安全，SDK版本号2.1.0.15128之后的许可登录将不再支持json登录的方法。
			String Param = "{\"license_id\":"+softwareId+"}";
			// 可以根据LIC_USER_DATA_TYPE来获取公开区、读写区和只读取的数据区大小。根据数据区大小和数据偏移读取数据区内容。
			byte[] ReadBuff;
			long DataSize = 0;
			DataSize = SSRuntimeEasy.SlmPubDataGetsizeEasy(Handle, softwareId);
			ret = SSRuntimeEasy.SlmGetLastError();
			if (ret == ErrorCode.SS_OK) {
				System.out.println("SlmUserDataGetsizeEasy success!");
				if (DataSize != 0) {
					ReadBuff = new byte[(int) DataSize];
					ret = SSRuntimeEasy.SlmPubDataReadEasy(Handle, softwareId, ReadBuff, 0, DataSize);
					if (ret == ErrorCode.SS_OK) {
						System.out.println("SlmUserDataReadEasy success!");
						System.out.println(new String(ReadBuff));
						authToken = JsonUtils.jsonToBean(new String(ReadBuff,"UTF8"), AuthToken.class);
					} else {
						System.out.printf("SlmUserDataReadEasy failure : 0x%08X!  %s\n", ret, SSRuntimeEasy.SlmErrorFormatEasy(ret, 2));
					}

				} else {
					System.out.println("No data!");
				}
			} else {
				System.out.printf("SlmUserDataGetsizeEasy failure : 0x%08X!  %s\n", ret, SSRuntimeEasy.SlmErrorFormatEasy(ret, 2));
			}
			SoftwareLicense license = readLicense();
			if(license!=null&&license.isEnable()){
				if(license.isLimited()){//限制时间
					Date endTime = license.getEndTime();
					authToken.setAuthTime(endTime.getTime()/1000L);
				}else{
					authToken.setAuthTime(0L);
				}
			}else{
				authToken.setAuthTime(-1L);
			}
		}catch (Throwable e){
			log.error("读取加密狗授权信息异常",e);
			return null;
		}
		return authToken;
	}

	@Override
	public SoftwareLicense readLicense() {
		long ret;
		long Handle = 0;
		ST_LOGIN_PARAM stLogin = new ST_LOGIN_PARAM();
		stLogin.size = stLogin.getSize();
		stLogin.license_id = softwareId;
		SoftwareLicense license=null;
		Object findLic = new Object();
		findLic = SSRuntimeEasy.SlmFindLicenseEasy(softwareId, INFO_FORMAT_TYPE.JSON.get());
		ret = SSRuntimeEasy.SlmGetLastError();
		if (ret == ErrorCode.SS_OK) {	
			license=new SoftwareLicense();
			SSRuntimeEasy.SlmFreeEasy(findLic);
			license.setEnable(false);
		} else {
		}
		// stLogin.login_mode=SSDefines.SLM_LOGIN_MODE_LOCAL;
		Handle = SSRuntimeEasy.SlmLoginEasy(stLogin, INFO_FORMAT_TYPE.STRUCT.get()); // login by  struct
		ret = SSRuntimeEasy.SlmGetLastError();
		if (ret == ErrorCode.SS_OK && Handle != 0) {
			if(license==null){
				license=new SoftwareLicense();
			}
			// test SlmGetInfoEasy SlmFreeEasy
			Object lic_info = new Object();
			lic_info = SSRuntimeEasy.SlmGetInfoEasy(Handle, INFO_TYPE.LICENSE_INFO.get(), INFO_FORMAT_TYPE.JSON.get());
			ret = SSRuntimeEasy.SlmGetLastError();
//			log.info(lic_info);
			if (ret == ErrorCode.SS_OK) {
				SSRuntimeEasy.SlmFreeEasy(lic_info);
				SLMLicense slmLicense=new Gson().fromJson(lic_info.toString(), SLMLicense.class);
				license.setLicenseId(slmLicense.developer_id+"_"+softwareId);
				license.setEnduser(slmLicense.guid);
				license.setLicenseType(slmLicense.type.equals("local")?"硬件锁":(slmLicense.type.equals("cloud")?"云锁":slmLicense.type));
				license.setEnable(slmLicense.enable);
				if(slmLicense.start_time!=null){
					try{license.setStartTime(new Date(slmLicense.start_time*1000));}catch (Exception e) {}
				}else if(slmLicense.first_use_time!=null){
					try{license.setStartTime(new Date(slmLicense.first_use_time*1000));}catch (Exception e) {}
				}else{
					try{license.setStartTime(new Date());}catch (Exception e) {}
				}
				if(slmLicense.end_time!=null){
					try{license.setEndTime(new Date(slmLicense.end_time*1000));}catch (Exception e) {}
				}
				if(slmLicense.span_time!=null&&license.getStartTime()!=null){
					try{license.setEndTime(new Date(license.getStartTime().getTime()+slmLicense.span_time*1000));}catch (Exception e) {}
				}
				
				if(slmLicense.enable){
					if(slmLicense.end_time ==null){
						license.setLimited(false);
					}
				}
				return license;
			} else {
				
			}
			log.info("SlmLoginEasy success!");
		} else {
			log.error("SlmLoginEasy failure : ErrorCode = "+ret+"!   SLM Handle ="+Handle+" \n" );
		}
		
		return license;
	}

	@Override
	public SoftwareLicense refeash() {
		// TODO Auto-generated method stub
		return (license = readLicense());
	}
}
